/* ====================================================
#   Copyright (C) 2021-2025  All rights reserved.
#
#   Author        : Jinjing Li
#   Email         : josiahleeoaa@outlook.com
#   File Name     : u_generator.C
#   Last Modified : 2025-05-18 17:32
#   Describe      : Neutron event generator for nuclear physics experiments
#                   - Updated parameter handling (removed unused params)
#                   - Added detailed command line usage documentation
#                   - Improved code comments
#
#   Features:
#   - Supports spontaneous fission neutron generation (U238 default)
#   - Supports (alpha,n) reaction neutron generation
#   - Configurable via command line options
#
#   Usage Examples:
#   1. Spontaneous fission mode (U-238):
#      ./u_generator -i 92238 -n 1000000 -o output.txt -S
#   2. Alpha-N reaction mode (Th-232):
       ./u_generator -i 90232 -t b11 -s 1 -n 1000 -A -v GeneratorInputs2025/DayaBay_PMT_pyrex -o output.txt
       ./u_generator -i 90232 -t b11 -s 100 -n 1000 -A -v GeneratorInputs2025/DayaBay_PMT_pyrex -o output.txt
#
#   Command Line Options:
#   -i : Isotope number (e.g. 92238 for U-238)
#   -n : Number of events to generate (default: 1e9)
#   -o : Output filename (stdout if not specified)
#   -S : Enable spontaneous fission mode
#   -A : Enable alpha-n reaction mode
#   -m : Material name for alpha-n mode (default: Acrylic)
#   -t : Target nucleus for alpha-n mode (default: b11)
#   -s : State index for alpha-n mode (-1 for all states)
#   -d : Nuclear database (default: JENDL)
#
#   Command Line Options:
#   -i : Isotope number (e.g. 92238 for U-238)
#   -n : Number of events to generate
#   -o : Output filename (stdout if not specified)
#   -S : Enable spontaneous fission mode
#   -A : Enable alpha-n reaction mode
#   -m : Material name for alpha-n mode
#   -t : Target nucleus for alpha-n mode
#   -s : State index for alpha-n mode
#   -v : Data version (lijj/ihep)
#   -d : Nuclear database (default: JENDL)
#
# ====================================================*/

#include <cstdio>
#include <cstdlib>
#include <cmath>
#include <unistd.h>
#include <iostream>

#include "libAlphaN.h"
#include "libSpFission.h"

// Configuration options
// #define OUTPUT_2_ROOT_FILE // Enables ROOT file output capability

using namespace std;

// Global variables
string pwd;                 // Stores the executable's directory path
string data_version_global; // Stores the selected data version (lijj/ihep)

string get_data_version(const string &opt)
{
    return opt;
}

int main(int argc, char *argv[])
{
    // Default configuration parameters
    // Spontaneous fission parameters
    int isotope = 92238;               // Default isotope: U-238
    unsigned int nEvents = 1000000000; // Default event count

    // Alpha-N reaction parameters
    string target = "b11";     // Default target nucleus
    int state_idx = -1;        // Default state index
    string database = "JENDL"; // Default nuclear database

    // Output configuration
    string outFilename = ""; // Output filename (empty = stdout)
    FILE *stream = stdout;   // Output stream

    // Mode flags
    int result;                  // getopt return value
    bool flag_spfission = false; // Spontaneous fission mode flag
    bool flag_alphaN = false;    // Alpha-N reaction mode flag

    string exe_name = argv[0];
    int exe_idx = exe_name.find_last_of("/");
    pwd = exe_name.substr(0, exe_idx) + "/";
    // cout << "EXE path: " << pwd << endl;

    // Command line argument processing
    // Supported options:
    // -d : Nuclear database name (default: JENDL)
    // -n : Number of events to generate
    // -o : Output filename (stdout if not specified)
    // -t : Target nucleus (for alpha-n mode)
    // -s : State index (for alpha-n mode)
    // -i : Isotope number (e.g. 92238 for U-238)
    // -A : Enable alpha-n reaction mode
    // -S : Enable spontaneous fission mode
    // -v : Data version (lijj/ihep)
    while ((result = getopt(argc, argv, "d:n:o:t:s:i:ASv:")) != -1)
    {
        switch (result)
        {
        case 'n':
            nEvents = atoi(optarg);
            break;
        case 'i':
            isotope = atoi(optarg);
            break;
        case 'o':
            outFilename = optarg;
            break;
        case 't':
            target = optarg;
            break;
        case 'd':
            database = optarg;
            break;
        case 's':
            state_idx = atoi(optarg);
            break;
        case 'A':
            flag_alphaN = true;
            break;
        case 'S':
            flag_spfission = true;
            break;
        case 'v':
            data_version_global = get_data_version(string(optarg));
            break;
        }
    }

    if (outFilename != "")
    {
        stream = fopen(outFilename.c_str(), "w");
        if (stream == NULL)
        {
            printf("Please enter a valid filename.\n");
            exit(0);
        }
    }
    if (flag_alphaN)
    {
        // Alpha-N reaction neutron generation mode
        if (state_idx < MAX_LEVELS)
        {
            // Single state mode
            // Generate alpha-n reaction neutrons for single state
            // Parameters:
            // isotope - target isotope number
            // target - target nucleus (e.g. "b11")
            // state_idx - specific state index
            // nEvents - number of events to generate
            // stream - output file stream
            // Material - material name
            // database - nuclear database name
            generator_alphan_basedon_sundean(isotope, target, state_idx,
                                             nEvents, stream, database);
        }
        else
        {
            // Multi-state mode:
            // When state_idx > 100, we use multiple states together.
            // The actual number of states = state_idx - 100
            // Example: state_idx=105 means use 5 states together
            // Generate alpha-n reaction neutrons for multiple states
            // Parameters:
            // isotope - target isotope number
            // target - target nucleus (e.g. "b11")
            // nEvents - number of events to generate
            // stream - output file stream
            // Material - material name
            // database - nuclear database name
            // state_idx - 100 - number of states to consider
            generator_alphan_basedon_sundean(isotope, target, nEvents,
                                             stream, database);
        }
        return 0;
    }

    if (flag_spfission)
    {
        // Spontaneous fission neutron generation mode
        // Generate spontaneous fission neutrons
        // Parameters:
        // isotope - fissioning isotope number
        // nEvents - number of events to generate
        // stream - output file stream
        generator_spfission_basedon_freya_fissevent(isotope, nEvents, stream);
        return 0;
    }

    return 0;
}
